package blackstar.plugin.performance.stat;

import java.util.LinkedHashMap;
import java.util.Map;

import blackstar.performance.logger.info.LoadChainNode;

public class MergeLoadChainNode
{
	private String className;
	private String method;
	private long totalCount = 0; // 总调用次数
	private long totalTime = 0; // 总调用时间
	private MergeLoadChainNode parent; // 父节点
	private Map<String, MergeLoadChainNode> children = new LinkedHashMap<String, MergeLoadChainNode>();

	public MergeLoadChainNode(LoadChainNode loadChainNode,
			MergeLoadChainNode parent)
	{
		this.className = loadChainNode.getClassName();
		this.method = loadChainNode.getMethod();

		this.parent = parent;
		merge(loadChainNode);
	}

	public MergeLoadChainNode(LoadChainNode loadChainNode)
	{
		this(loadChainNode, null);
	}

	public void merge(LoadChainNode loadChainNode)
	{
		long time = loadChainNode.getTimeNano();
		if (time > 0)
		{
			this.totalCount++;
			this.totalTime += time;

			if (loadChainNode.getChildren() != null)
			{
				for (LoadChainNode node : loadChainNode.getChildren())
				{
					String fullName = node.getFullName();
					MergeLoadChainNode mergeNode = children.get(fullName);
					if (mergeNode != null)
					{
						mergeNode.merge(node);
					} else
					{
						mergeNode = new MergeLoadChainNode(node, this);
						children.put(fullName, mergeNode);
					}

					mergeNode = null;
				}
			}
		}
	}

	public String getFullName()
	{
		return this.className + "." + this.method;
	}

	public String getClassName()
	{
		return className;
	}

	public String getMethod()
	{
		return method;
	}

	public long getTotalCount()
	{
		return totalCount;
	}

	public long getTotalTime()
	{
		return totalTime;
	}

	public MergeLoadChainNode getParent()
	{
		return parent;
	}

	public MergeLoadChainNode getTop()
	{
		MergeLoadChainNode top = this.parent;
		if (top == null)
		{
			return null;
		}
		
		while (top.getParent() != null)
		{
			top = top.getParent();
		}
		
		return top;
	}

	/**
	 * 深度优先遍历
	 * 
	 * @param visitor
	 */
	public void visitDepthFirst(IMergeLoadChainNodeVisitor visitor)
	{
		visitor.visitBegin(this);
		if (this.children != null)
		{
			for (MergeLoadChainNode node : this.children.values())
			{
				node.visitDepthFirst(visitor);
			}
		}
		visitor.visitEnd(this);
	}
}